-- 可能是其他模组hook这个方法没有传mod_name，已经在2个大型mod发现这个问题
-- 情况为： 地图界面右键显示动作，但是点击无反应
AddComponentPostInit("playercontroller", function(playercontroller)
        local oldOnMapAction = playercontroller.OnMapAction
        playercontroller.OnMapAction = function(self, actioncode, position, maptarget, mod_name, ...)
            local act = MOD_ACTIONS_BY_ACTION_CODE[modname] and MOD_ACTIONS_BY_ACTION_CODE[modname][actioncode] or
                nil
            if (mod_name == nil or modname == mod_name) and act and act.map_action then
                act.target = maptarget
                local LMBaction, RMBaction = self:GetMapActions(position, maptarget, act)

                if self.ismastersim then
                    if act.rmb then
                        if RMBaction then
                            self.locomotor:PushAction(RMBaction, true)
                        end
                    else
                        if LMBaction then
                            self.locomotor:PushAction(LMBaction, true)
                        end
                    end
                elseif self.locomotor == nil then
                    if act.rmb then
                        if RMBaction and RMBaction.action.pre_action_cb then
                            RMBaction.action.pre_action_cb(RMBaction)
                        end
                    else
                        if LMBaction and LMBaction.action.pre_action_cb then
                            LMBaction.action.pre_action_cb(LMBaction)
                        end
                    end
                    SendRPCToServer(RPC.DoActionOnMap, actioncode, position.x, position.z, maptarget, mod_name)
                elseif self:CanLocomote() then
                    if act.rmb then
                        RMBaction.preview_cb = function()
                            SendRPCToServer(RPC.DoActionOnMap, actioncode, position.x, position.z, maptarget,
                                modname)
                        end
                        self.locomotor:PreviewAction(RMBaction, true)
                    else
                        LMBaction.preview_cb = function()
                            SendRPCToServer(RPC.DoActionOnMap, actioncode, position.x, position.z, maptarget,
                                modname)
                        end
                        self.locomotor:PreviewAction(LMBaction, true)
                    end
                end
                return     
            end
            return oldOnMapAction(self, actioncode, position, maptarget, mod_name, ...)
        end
    end)


--附带个酷酷的指令 输入/i23bugfix_map触发 
local UserCommands = {}
do  --临时启用地图动作修复  
    local modname = modname
    local function OnMapAction(self, actioncode, position, maptarget, mod_name, ...)
        local act = MOD_ACTIONS_BY_ACTION_CODE[modname] and MOD_ACTIONS_BY_ACTION_CODE[modname][actioncode] or
                nil
        if (mod_name == nil or modname == mod_name) and act and act.map_action then
            act.target = maptarget
            local LMBaction, RMBaction = self:GetMapActions(position, maptarget, act)

            if self.ismastersim then
                if act.rmb then
                    if RMBaction then
                        self.locomotor:PushAction(RMBaction, true)
                    end
                else
                    if LMBaction then
                        self.locomotor:PushAction(LMBaction, true)
                    end
                end
            elseif self.locomotor == nil then
                if act.rmb then
                    if RMBaction and RMBaction.action.pre_action_cb then
                        RMBaction.action.pre_action_cb(RMBaction)
                    end
                else
                    if LMBaction and LMBaction.action.pre_action_cb then
                        LMBaction.action.pre_action_cb(LMBaction)
                    end
                end
                SendRPCToServer(RPC.DoActionOnMap, actioncode, position.x, position.z, maptarget, mod_name)
            elseif self:CanLocomote() then
                if act.rmb then
                    RMBaction.preview_cb = function()
                        SendRPCToServer(RPC.DoActionOnMap, actioncode, position.x, position.z, maptarget,
                            modname)
                    end
                    self.locomotor:PreviewAction(RMBaction, true)
                else
                    LMBaction.preview_cb = function()
                        SendRPCToServer(RPC.DoActionOnMap, actioncode, position.x, position.z, maptarget,
                            modname)
                    end
                    self.locomotor:PreviewAction(LMBaction, true)
                end
            end
            return     
        end
        return self:i23bf_OnMapAction(actioncode, position, maptarget, mod_name, ...)
    end

    UserCommands.i23bugfix_map = {
        serverfn = function(params, inst)
            if not inst then
                return
            end

            local playercontroller = inst.components.playercontroller
            if playercontroller and not playercontroller.i23bf_OnMapAction then
                playercontroller.i23bf_OnMapAction = playercontroller.OnMapAction
                playercontroller.OnMapAction = OnMapAction
            end

            local talker = inst.components.talker
            if talker then 
                talker:Say("已启用：地图动作临时修复")
            end
        end,
        localfn = function(params, inst)
            local playercontroller = inst and inst.components.playercontroller
            if playercontroller and not playercontroller.i23bf_OnMapAction then
                playercontroller.i23bf_OnMapAction = playercontroller.OnMapAction
                playercontroller.OnMapAction = OnMapAction
            end
        end,
    }
end
-- permission
-- NONE（无权限）
-- • USER（普通玩家）
-- • MODERATOR（管理员）
-- • ADMIN（服主/超级管理员）
for k, v in pairs(UserCommands) do
    local data = {
        aliases = nil,      --命令的别名列表
        prettyname = nil,   --命令的显示名称 default to STRINGS.UI.BUILTINCOMMANDS.EMOTE.PRETTYNAME
        desc = nil,         --default to STRINGS.UI.BUILTINCOMMANDS.EMOTE.DESC

        permission = GLOBAL.COMMAND_PERMISSION.USER,    --使用权限
        vote = false,   --是否以投票方式执行
        confirm = false,    --执行前是否需要确认（如 true 会弹出确认窗口）
        --hasaccessfn function(command, caller, targetid) 自定义函数，检查玩家是否有权使用该命令（返回 boolean）。
        --canstartfn function(command, caller, targetid) 自定义函数，检查命令是否可被发起（如检查游戏状态）。

        --localfn   本地执行的函数（客户端）
        --serverfn  服务器端执行的函数
        params = {},    --定义命令参数（如 {name="player", type="string"}）
        --paramsoptional    --{boolean, ...} 标记哪些参数是可选的（与 params 顺序对应）。
        
        usermenu = false,   --是否在玩家菜单中显示
        servermenu = false, --是否在服务器管理菜单中显示
        emote = false,      --是否作为表情命令
        slash = true,       --可以通过/命令形式使用
        --menusort          --在菜单中的排序优先级（数字越小越靠前，默认 100）

        --voteminpasscount  --投票通过所需的最小赞成票数
        --voteminstartage   --发起投票的玩家需满足的最小游戏时长（秒）。
        --votecanstartfn    --自定义函数，检查投票是否可被发起。function(command, caller, targetid)
        --voteresultfn      --自定义函数，处理投票结果并返回是否通过。function(params, voteresults)
        --voteallownotvoted --是否允许未投票的玩家影响结果（默认 false）。
        --cantargetself     --是否允许以自己为目标（如 false 时不能对自己发起投票）。
        --cantargetadmin    --是否允许以管理员为目标（如 false 时不能对管理员发起投票）。

        --aliasfor              --内部使用，标记该命令是另一个命令的别名（如 aliasfor="stopvote"）。
        --hash                  --内部使用，命令的唯一哈希值（通过 smallhash(name) 生成）。
        --requires_item_type    --需要玩家拥有特定物品才能使用该命令（如皮肤限定命令）。
    }

    for a, b in pairs(v) do
        data[a] = b
    end
    AddUserCommand(k, data)
end